package org.ectar.papi
{
	import flash.system.Security;
	
	import mx.rpc.events.FaultEvent;
	import mx.rpc.events.ResultEvent;
	import mx.rpc.http.mxml.HTTPService;

	/**
	 * Data Service which will work with Goole via HTTP
	 * Contains HTPService inside and set of wrappers which will hep you to do simple data requests.
	 * 
	 * Example of use:
	 * 
	 * <code>var gService:GDataService = new GDataService();</code>
	 * <code>gService.userName = username;</code>
	 * <code>gService.projection = GDATA_PROJECTION_API;</code>
	 * <code>gService.getPhotosByAlbum("MyWedding",handleAlbumPhotos);</code>
	 * 
	 * where <code>handleAlbumPhotos</code> callback function which basically handles ResultEvent from internal HTTP service.
	 * 
	 * */
	public class GDataService
	{
		/** Specifies type of projection API */
		public static var GDATA_PROJECTION_API:String = "api";
		/** Specifies type of projection BASE */
		public static var GDATA_PROJECTION_BASE:String = "base";

		private static var GDATA_SERVICE_URL:String = "http://photos.googleapis.com/data/feed/"
		private static var GDATA_SERVICE_URL2:String = "http://picasaweb.google.com/data/feed/"
		private static var GDATA_SERVICE_PROXY_URL:String = "http://picasafx.com/proxy.php?url="
		private static var GDATA_IMAGE_PROXY_URL:String = "http://picasafx.com/loadImage.php?file=" 
		private static var GDATA_COMMUNITY:String = "/all";
		private static var GDATA_USER_PREFFICS:String = "/user/";
		private static var GDATA_ALBUM_PREFFICS:String = "/album/";
		private static var GDATA_ALBUMID_PREFFICS:String = "/albumid/";
		private static var GDATA_PHOTOID_PREFFICS:String = "/photoid/";
		
		private static var GDATA_PHOTO_KIND:String = "?kind=photo";
		private static var GDATA_ALBUM_KIND:String = "?kind=album";
		
		private static var GDATA_STARTINDEX_PARAMETER:String = "start-index";
		private static var GDATA_MAXRESULTS_PARAMETER:String = "max-results";
		private static var GDATA_KIND_PARAMETER:String = "kind";
		private static var GDATA_ACCESS_PARAMETER:String = "access";
		private static var GDATA_QUERY_PARAMETER:String = "q";
		
		private static var GDATA_AMP:String = "&";
		private static var GDATA_AMP_SAFE:String = "%26";
		
		private static var LOCAL:int = 0;
		private static var REMOTE:int = 1;
				
		public function GDataService():void {
			service = new HTTPService();
			service.useProxy = false;
			if(!proxied)
				Security.loadPolicyFile(policyFile);
		}
		
		private var _userName:String;
		
		private var _requestURL:String;
		
		public var service:HTTPService;
				
		private var _projection:String;
		
		private var _deployment:int;
		
		private static var policyFile:String = "http://photos.googleapis.com/data/crossdomain.xml";
				
		[Bindable] private var apm:String;
		
		[Bindable] private var _proxied:Boolean = false;
		/**
		 * Indicates type of deployment of Aplication. 
		 * Proxy is simple redirector which redirects all query from application to googledata services
		 * This is necessary workaround to get away from problem with Google Data crossdomain.xml restrictions
		 * 
		 * proxied = false - not require proxy
		 * proxied = true - require proxy;
		 * */
		public function set proxied(value:Boolean):void {
			_proxied = value;
			apm = _proxied?GDATA_AMP_SAFE:GDATA_AMP
		}
		
		public function get proxied():Boolean {
			return _proxied;
		}
		
		/**
		 * Set the user name for current GDataService instance
		 * */
		public function set userName(value:String):void {
			_userName = value;		
		}
		
		/**
		 * Returns user name of current GDataService instance
		 * */
		public function get userName():String {
			return _userName;
		}
		
		/**
		 * Specifies type of projection for current GDataService instance
		 * Can be "api" or "base"
		 * */
		public function set projection(value:String):void {
			_projection = value;		
		}
		
		/**
		 * Returns type of projection of GDataService instance
		 * */
		public function get projection():String {
			return _projection;
		}
		
		/**
		 * Wrapper function which does real HTTP request and return result to user specified callback function
		 * This function request a feed which contains all photos in the specified album.
		 * 
		 * @param albumName  - String represents album name
		 * @param callbackResult - callback function of result processing
		 * @param callbackFailed - callback function for processing faulties
		 * @param startIndex - offset from the beginning of the list
		 * @param maxResults - specifies maximum number of entries returned
		 * 
		 * */
		public function getPhotosByAlbum(albumName:String, callbackResult:Function, callbackFailed:Function, startIndex:int = 0, maxResults:int = -1):void {
			var url:String = (proxied?GDATA_SERVICE_PROXY_URL:"") + GDATA_SERVICE_URL + projection 
							+ GDATA_USER_PREFFICS + userName 
							+ GDATA_ALBUM_PREFFICS 
							+ albumName + GDATA_PHOTO_KIND
							+ (startIndex==0?"":apm + GDATA_STARTINDEX_PARAMETER + "=" + startIndex) + 
							(maxResults==-1?"":apm + GDATA_MAXRESULTS_PARAMETER + "=" + maxResults);
							
			service.url = url;
			
			service.method = "GET";
			
			service.resultFormat = "e4x";
			
			service.addEventListener(ResultEvent.RESULT, callbackResult);
			service.addEventListener(FaultEvent.FAULT, callbackFailed);
			
			service.send();
		}
		
		/**
		 * Wrapper function which does real HTTP request and return result to user specified callback function
		 * This function request a feed which contains an album content for given albumId.
		 * If album isn't public function return nothing
		 *  
		 * @param albumID - an album ID
		 * @param callbackResult - callback function of result processing
		 * @param callbackFailed - callback function for processing faulties
		 * @param startIndex - offset from the beginning of the list
		 * @param maxResults - specifies maximum number of entries returned
		 * 
		 */
		public function getPhotosByAlbumId(albumID:String, callbackResult:Function, callbackFailed:Function, startIndex:int = 0, maxResults:int = -1):void {
			service.url = (proxied?GDATA_SERVICE_PROXY_URL:"") + GDATA_SERVICE_URL + projection 
							+ GDATA_USER_PREFFICS + userName + GDATA_ALBUMID_PREFFICS 
							+ albumID + GDATA_PHOTO_KIND
							+ (startIndex==0?"":apm + GDATA_STARTINDEX_PARAMETER + "=" + startIndex) + 
							(maxResults==-1?"":apm + GDATA_MAXRESULTS_PARAMETER + "=" + maxResults);							
							
			//service.url = "assets/photoshow/index.xml";							
			
			service.method = "GET";
			
			service.resultFormat = "e4x";
			
			service.addEventListener(ResultEvent.RESULT, callbackResult);
			service.addEventListener(FaultEvent.FAULT, callbackFailed);
			
			service.send();
		}		
		
		/**
		 * Wrapper function which does real HTTP request and return result to user specified callback function
		 * This function request a feed which contains all photo details by photoId iin to specified album by album ID
		 * If photo isn't public function return nothing
		 * 
		 * @param photoId - an ID of photo
		 * @param albumId - an ID of album
		 * @param callbackResult - callback function of result processing
		 * @param callbackFailed - callback function for processing faulties
		 * 
		 */
		public function getPhotoById(photoId:String, albumId:String, callbackResult:Function, callbackFailed:Function):void {
			service.url = (proxied?GDATA_SERVICE_PROXY_URL:"") + GDATA_SERVICE_URL + projection + GDATA_USER_PREFFICS + userName + GDATA_ALBUMID_PREFFICS 
							+ albumId + GDATA_PHOTOID_PREFFICS + photoId;
							
			service.method = "GET";
			
			service.resultFormat = "e4x";
			
			service.addEventListener(ResultEvent.RESULT, callbackResult);
			service.addEventListener(FaultEvent.FAULT, callbackFailed);
			
			service.send();
		}
		
		/**
		 * Wrapper function which does real HTTP request and return result to user specified callback function
		 * This function requests feed which contains all possible albums for given user.
		 * For now this function returns a list of only Public albums
		 * 
		 * @param callbackResult - callback function of result processing
		 * @param callbackFailed - callback function for processing faulties
		 * @param startIndex - offset from the beginning of the list
		 * @param maxResults - specifies maximum number of entries returned
		 * 
		 * */		
		public function getAlbumsForCurrentUser(callbackResult:Function, callbackFailed:Function, startIndex:int = 0, maxResults:int = -1):void {
			
			var url:String = (proxied?GDATA_SERVICE_PROXY_URL:"") + GDATA_SERVICE_URL + projection 
							+ GDATA_USER_PREFFICS + userName + "/" + GDATA_ALBUM_KIND
							+ (startIndex==0?"":apm + GDATA_STARTINDEX_PARAMETER + "=" + startIndex) + 
							(maxResults==-1?"":apm + GDATA_MAXRESULTS_PARAMETER + "=" + maxResults);
											
			service.url = url;
							
			service.method = "GET";
			
			service.resultFormat = "e4x";
			
			service.addEventListener(ResultEvent.RESULT, callbackResult);
			service.addEventListener(FaultEvent.FAULT, callbackFailed);			
			
			service.send();
			
			//http://picasaweb.google.com/data/feed/projection/user/userID/?kind=kinds
		}
		
		/**
		 * Wrapper function which does real HTTP request and return result to user specified callback function
		 * This function requests feed which contains search result specifies in searchTerm. 
		 * Set of resulting pictures can be limited by <code>startIndex</code> and <code>maxResults</code>
		 * this function returns a list of only Public pictures
		 *  
		 * @param searchTerm - search string which is term for image search
		 * @param callbackResult - callback function of result processing
		 * @param callbackFault - callback function of fault processing
		 * @param startIndex - offset from the beginning of the list
		 * @param maxResults - specifies maximum number of entries returned
		 * 
		 * */
		public function getPhotosByTerm(searchTerm:String, callbackResult:Function, callbackFault:Function, startIndex:int = 0, maxResults:int = -1):void {
			
			var url:String = (proxied?GDATA_SERVICE_PROXY_URL:"") + GDATA_SERVICE_URL + projection + 
							GDATA_COMMUNITY + GDATA_PHOTO_KIND + 
							apm + GDATA_QUERY_PARAMETER + "=" + searchTerm + 
							(startIndex==0?"":apm + GDATA_STARTINDEX_PARAMETER + "=" + startIndex) + 
							(maxResults==-1?"":apm + GDATA_MAXRESULTS_PARAMETER + "=" + maxResults);
			
			service.url = url;							
			
			service.method = "GET";
			
			service.resultFormat = "e4x";
			
			service.addEventListener(ResultEvent.RESULT, callbackResult);
			service.addEventListener(FaultEvent.FAULT, callbackFault);
			
			service.send();
		}
	}
}